package com.codermn.并发访问控制.栅栏CyclicBarrier;

import java.time.LocalDateTime;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * <p>
 *     CyclicBarrier的作用与上面的CountDownLatch相似，区别在于正向计数+1,
 *     只有达到条件才放行; 且支持通过调用reset()重置计数，而CountDownLatch则不行
 * </p>
 * @author jxau_scf
 * @date 2021/8/13 - 11:33
 */
public class CyclicBarrierTest {
    private void cyclicBarrierLogic(CyclicBarrier barrier, long sleep){
        try {
            System.out.println("准备执行：" + Thread.currentThread() + "  at:  " + LocalDateTime.now());
            Thread.sleep(sleep);
            int index = barrier.await();
            System.out.println("开始执行：" + index + "  thread:   " + Thread.currentThread() + "  at:  " + LocalDateTime.now());
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }

    public void testCyclicBarrier() throws InterruptedException {
        //达到两个工作线程才能继续往后执行
        CyclicBarrier barrier = new CyclicBarrier(2);

        //3秒后，下面两个线程才会输出，开始执行
        new Thread(()->cyclicBarrierLogic(barrier, 1000)).start();
        new Thread(()->cyclicBarrierLogic(barrier, 3000)).start();

        Thread.sleep(4000);
        //重置，可再次使用
        barrier.reset();
        new Thread(()->cyclicBarrierLogic(barrier,1)).start();
        new Thread(()->cyclicBarrierLogic(barrier,1)).start();
        Thread.sleep(10000);
    }
}
